package com.youlian.cloud.gateway.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * 基于eureka服务注册发现机制的实现,从注册中心获取项目
 * @author liuhx
 * @create 2019/08/05 10:55
 * @email liuhx@elab-plus.com
 **/

@Component
@Profile({"dev", "test", "uat"})
public class SwaggerConfiguration implements SwaggerResourcesProvider {

    @Autowired
    private RouteLocator routeLocator;

    @Autowired
    private DiscoveryClient discoveryClient;

//    @Value("${spring.application.name}")
//    private String applicationName;

//    @Primary
//    @Bean
//    @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
//    public SwaggerResourcesProvider swaggerResourcesProvider() {
//
//        return () -> {
//            List<Route> routes = routeLocator.getRoutes();
//            List<SwaggerResource> resources = new ArrayList<>();
////            routes.stream()
////                    .forEach(route -> resources.add(createResource(route.getId(), route.getId(), "1.0")));
//
//
//            /** 排除自身，将其他的服务添加进去 **/
//            discoveryClient.getServices().stream().forEach(name -> {
//                Optional<ServiceInstance> instanceOptional = discoveryClient.getInstances(name).stream().findFirst();
//                /***
//                 * 业务服务如果加了context-path配置,则进入if里面的操作，默认加上contextPath
//                 * server.servlet.context-path=/yinjihuan
//                 * eureka.instance.metadata-map.context-path=${server.servlet.context-path}
//                 * **/
//                if (instanceOptional.isPresent() && instanceOptional.get().getMetadata().containsKey(CONTEXT_PATH)) {
//                    String contexPath = instanceOptional.get().getMetadata().get("context-path");
//                    resources.add(swaggerResource(name, "/" + name + contexPath + "/v2/api-docs"));
//                } else {
//                    resources.add(swaggerResource(name, "/" + name + "/v2/api-docs"));
//                }
////            resources.add(swaggerResource(name, "/" + name + SWAGGER2URL));
//            });
//
//            return resources;
//        };
//    }

    private SwaggerResource createResource(String name, String location, String version) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation("/" + location + "/v2/api-docs");
        swaggerResource.setSwaggerVersion(version);
        return swaggerResource;
    }

    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList();
//        routeLocator.getRoutes().stream()
//                .forEach(route -> resources.add(createResource(route.getId().substring(EUREKA_SUB_PRIX.length()), route.getId(), "1.0")));


        /** 排除自身，将其他的服务添加进去 **/
        discoveryClient.getServices().stream().forEach(name -> {
            Optional<ServiceInstance> instanceOptional = discoveryClient.getInstances(name).stream().findFirst();
            /***
             * 业务服务如果加了context-path配置,则进入if里面的操作，默认加上contextPath
             * server.servlet.context-path=/yinjihuan
             * eureka.instance.metadata-map.context-path=${server.servlet.context-path}
             * **/
            if (instanceOptional.isPresent() && instanceOptional.get().getMetadata().containsKey(CONTEXT_PATH)) {
                String contexPath = instanceOptional.get().getMetadata().get("context-path");
                resources.add(swaggerResource(name, "/" + name + contexPath + "/v2/api-docs"));
            } else {
                resources.add(swaggerResource(name, "/" + name + "/v2/api-docs"));
            }
//            resources.add(swaggerResource(name, "/" + name + SWAGGER2URL));
        });

        return resources;
    }

//
//    /**
//     * swagger2默认的url后缀
//     */
    private static final String SWAGGER2URL = "/v2/api-docs";
    private static final String CONTEXT_PATH = "context-path";
//
//    @Autowired
//    private final DiscoveryClientRouteDefinitionLocator routeLocator;
    public static final String EUREKA_SUB_PRIX = "CompositeDiscoveryClient_";
//    public SwaggerConfiguration(DiscoveryClientRouteDefinitionLocator routeLocator) {
//        this.routeLocator = routeLocator;
//    }
//
//    @Override
//    public List<SwaggerResource> get() {
//        List<SwaggerResource> resources = new ArrayList();
//        routeLocator.getRouteDefinitions().subscribe(routeDefinition -> {
//            resources.add(swaggerResource(routeDefinition.getId().substring(EUREKA_SUB_PRIX.length()),routeDefinition.getPredicates().get(0).getArgs().get("pattern").replace("/**", SWAGGER2URL)));
//
//        });
//        return resources;
//    }
//
    private SwaggerResource swaggerResource(String name, String location) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion("2.0");
        return swaggerResource;

    }
}
